#pragma once
#include<iostream>
#include<functional>
#include<string>
#include <sys/types.h>
#include <sys/socket.h>
#include<vector>
#include <pthread.h>
#include"InetAddr.hpp"
#include"ThreadPool.hpp"
#include "LockGuard.hpp"
using namespace std;

using task_t = function<void()>;
class Route{
public:
    Route()
    {
        pthread_mutex_init(&_mutex, nullptr);
    }
    void CheckOnlineUser(const InetAddr& who)
    {
        LockGuard lockguard(&_mutex);
        for(auto& user:_online_user)
        {
            if(user==who)
            {
                return;
            }
        }
        _online_user.push_back(who);
    }
    void Offline(const InetAddr& who)
    {
        LockGuard lockguard(&_mutex);
        auto iter = _online_user.begin();
        for(;iter!=_online_user.end();iter++)
        {
            if(*iter==who)
            {
                _online_user.erase(iter);
                break;
            }
        }
    }
    void ForwardHelper(int sockfd,const string message,InetAddr who)
    {
        LockGuard lockguard(&_mutex);
        string send_message = "["+who.AddrStr()+"]#"+message;

        for(auto user: _online_user)
        {
            struct sockaddr_in peer = user.Addr();
            sendto(sockfd,send_message.c_str(),send_message.size(),0,(struct sockaddr*)&peer,sizeof(peer));
        }
    }
    void Forward(int sockfd,const string& message,InetAddr &who)//shui转发消息
    {
        //1.该用户是否存在用户列表中，如何在什么都不做，不在自动添加到用户列表
        CheckOnlineUser(who);
        //1.1 message==Quit则删除该用户
        if(message=="Quit"||message=="Q")
        {
            Offline( who);
        }

        //2.消息的转发，往哪转，转什么，此时who一定在列表里面
        //ForwardHelper(sockfd,message);
       task_t t = bind(&Route::ForwardHelper,this,sockfd,message,who);//创建一个任务和ForwardHelper进行绑定
       ThreadPool<task_t>::GetInstance()->Equeue(t);//任务入队列

    }
    ~Route()
    {
        pthread_mutex_destroy(&_mutex);
    }
private:
    vector<InetAddr> _online_user;
    pthread_mutex_t _mutex;
};